package com.magic.cd.util;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ibm.icu.text.SimpleDateFormat;
import com.magic.cd.entry.ReceiveMessageVO;
import com.magic.cd.entry.SendImageTextMessageVO;
import com.magic.cd.entry.SendImagetMessageVO;
import com.magic.cd.entry.SendMusicMessageVO;
import com.magic.cd.entry.SendTextMessageVO;
import com.magic.cd.entry.inner.Image;
import com.magic.cd.entry.inner.Music;
import com.magic.cd.entry.inner.Token;
import com.magic.cd.entry.inner.item;
import com.magic.cd.enums.MessageType;

/**
 * 专门用来处理微信的消息体
 * */
public class WeixinUtils {
	
	/**
	 * 演示项目使用缓存来保存token,实际项目最好保存到数据库
	 * */
	private static Token cache = null;
	private static long expire_time = 7000;	//文档规定7200秒，我们最好小于改时间,以保证token总是有效的
	
	public static String getToken(){
		//1.去数据库获取,或从缓存获取token
		//2.验证时间
		//3.如果时间已经过去或者为空，则请求微信服务器获取最新的token
		if(cache==null||(System.currentTimeMillis()-cache.getCreateTime())>expire_time){
			//4.如果发送了请求，将最新的token同步到数据库或缓存
			synchronized (WeixinUtils.class) {
				if(cache==null||(System.currentTimeMillis()-cache.getCreateTime())>expire_time){
					long currentTile = System.currentTimeMillis();
					String url = Const.TOKEN_URL;
					String res = HttpUtils.GET(url);
					res = JSON.parseObject(res).getString("access_token");
					cache = new Token();
					cache.setCreateTime(currentTile);
					cache.setToken(res);
				}
			}
		}
		return cache.getToken();
	}
	/**
	 * 构建文本消息
	 * */
	public static String toTextMsg(ReceiveMessageVO msg){
		SendTextMessageVO send = new SendTextMessageVO();
		send.setFromUserName(msg.getToUserName());
		send.setToUserName(msg.getFromUserName());
		send.setCreateTime(new Date().getTime());
		send.setMsgType(MessageType.text.getCode());
		send.setContent("服务器接收到："+msg.getContent());
		return MessageUtils.toXMLString(send, "xml");
	}
	
	/**
	 * 构建图文消息
	 * */
	public static String toImageTextMsg(ReceiveMessageVO msg){
		SendImageTextMessageVO send = new SendImageTextMessageVO();
		send.setCreateTime(new Date().getTime());
		send.setFromUserName(msg.getToUserName());
		send.setToUserName(msg.getFromUserName());
		send.setMsgType(MessageType.news.getCode());
		
		List<item> Articles = new ArrayList<item>();
		item i1 = new item();
		i1.setDescription("你好，欢迎您关注我们的微信号，希望我们能为您带来更佳优质的服务和更佳美好的用户体验！当前时间："
		+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		i1.setTitle("图文消息测试");
		i1.setPicUrl("http://7u2in2.com1.z0.glb.clouddn.com/e.png");
		i1.setUrl("http://mp.weixin.qq.com/s?__biz=MzI0OTA3NjQ0Nw==&mid=208185520&idx=1&sn=a4c626fd19e6456f9be5335b3891651e&scene=18#wechat_redirect");
		Articles.add(i1);
		
		send.setArticleCount(Articles.size());
		send.setArticles(Articles);
		
		return MessageUtils.toXMLString(send, "xml");
	}
	
	/**
	 * 构建图文消息
	 * */
	public static String toDoubleImageTextMsg(ReceiveMessageVO msg){
		SendImageTextMessageVO send = new SendImageTextMessageVO();
		send.setCreateTime(new Date().getTime());
		send.setFromUserName(msg.getToUserName());
		send.setToUserName(msg.getFromUserName());
		send.setMsgType(MessageType.news.getCode());
		
		List<item> Articles = new ArrayList<item>();
		item i1 = new item();
		i1.setDescription("点击图片，查看更多萌图！当前时间："
		+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		i1.setTitle("萌图多多");
		i1.setPicUrl("http://7u2in2.com1.z0.glb.clouddn.com/a.png");
		i1.setUrl("http://www.baidu.com");
		
		item i2 = new item();
		i2.setDescription("你好，点击图片查看更多萌图！当前时间："
		+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		i2.setTitle("点击图片查看更多萌图");
		i2.setPicUrl("http://7u2in2.com1.z0.glb.clouddn.com/d.png");
		i2.setUrl("http://www.baidu.com");
		
		Articles.add(i1);
		Articles.add(i2);
		
		send.setArticleCount(Articles.size());
		send.setArticles(Articles);
		
		return MessageUtils.toXMLString(send, "xml");
	}
	
	/**
	 * 构建音乐消息
	 * */
	private static long thumbLastTime = -1;//测试的时候做一个缓存，实际项目中应该是静态资源要单独管理，临时文件时间为3天
	private static String thumbId = "";
	public static String toMusicMsg(ReceiveMessageVO msg){
		SendMusicMessageVO send = new SendMusicMessageVO();
		send.setCreateTime(new Date().getTime());
		send.setFromUserName(msg.getToUserName());
		send.setToUserName(msg.getFromUserName());
		send.setMsgType(MessageType.music.getCode());
		
		Music music = new Music();
		music.setDescription("夏日清风，车站那悠扬婉转的惜别...");
		music.setHQMusicUrl("http://7u2in2.com1.z0.glb.clouddn.com/%E6%9D%8E%E5%81%A5_%E8%BD%A6%E7%AB%99.mp3");
		music.setMusicUrl("http://7u2in2.com1.z0.glb.clouddn.com/%E6%9D%8E%E5%81%A5_%E8%BD%A6%E7%AB%99.mp3");
		music.setTitle("车站");
		
		//缩略图片消息需要事先将图片上传到微信服务器，上传案例参考HttpUtilsTest.upload方法
		//临时图片只有三天时间有效期
		if((System.currentTimeMillis()-thumbLastTime)>259000){
			//演示项目资源放在了classpath，实际项目不能放在这里
			String path = msg.getRealPath()+"/image/small_a.png";
			try {
				thumbId = WeixinUtils.upload(path, getToken(), "thumb");
				thumbLastTime = System.currentTimeMillis();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		music.setThumbMediaId(thumbId);
		send.setMusic(music);
		
		return MessageUtils.toXMLString(send, "xml");
	}
	
	/**
	 * 构建测试引导文本消息
	 * */
	public static String toTestMsg(ReceiveMessageVO msg){
		SendTextMessageVO send = new SendTextMessageVO();
		send.setCreateTime(new Date().getTime());
		send.setFromUserName(msg.getToUserName());
		send.setToUserName(msg.getFromUserName());
		send.setMsgType(MessageType.text.getCode());
		send.setContent("欢迎使用测试导航栏，测试关键字：\n\n"
						+"1.文本      测试文本消息\n"
		                +"2.图片      测试图文消息\n"
		                +"3.音乐      测试音乐消息\n"
		                +"4.图文      测试文本图片\n"
		                +"5.多个图文     测试多图文\n\n"
		                +"回复help,调出此导航界面！");
		
		return MessageUtils.toXMLString(send, "xml");
	}
	
	/**
	 * 构建欢迎界面文本消息
	 * */
	public static String toLoginMsg(ReceiveMessageVO msg){
		SendTextMessageVO send = new SendTextMessageVO();
		send.setCreateTime(new Date().getTime());
		send.setFromUserName(msg.getToUserName());
		send.setToUserName(msg.getFromUserName());
		send.setMsgType(MessageType.text.getCode());
		send.setContent("欢迎关注我们的公众号，下面是一些测试的命令：\n\n"
		                +"1.文本      测试文本消息\n"
		                +"2.图片      测试图文消息\n"
		                +"3.音乐      测试音乐消息\n"
		                +"4.图文      测试文本图片\n"
		                +"5.多个图文     测试多图文\n\n"
		                +"回复help,调出此导航界面！");
		
		return MessageUtils.toXMLString(send, "xml");
	}
	
	/**
	 * 创建菜单
	 * */
	public static boolean createMeun(String json){
		//创建菜单接口，来自于文档
		String url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+getToken();
		String str  = HttpUtils.POST(url, json);
		System.out.println("创建结果："+str);
		JSONObject jsons = JSON.parseObject(str);
		if(jsons.getInteger("errcode")==0){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 构建图片消息
	 * */
	private static long imageLastTime = -1;//测试的时候做一个缓存，实际项目中应该是静态资源要单独管理，临时文件时间为3天
	private static String imageId = "";
	public static String toImageMsg(ReceiveMessageVO msg){
		SendImagetMessageVO send = new SendImagetMessageVO();
		send.setCreateTime(new Date().getTime());
		send.setFromUserName(msg.getToUserName());
		send.setToUserName(msg.getFromUserName());
		send.setMsgType(MessageType.image.getCode());
		
		//图片消息需要事先将图片上传到微信服务器，上传案例参考HttpUtilsTest.upload方法
		Image image = new Image();
		
		//图片消息需要事先将图片上传到微信服务器，上传案例参考HttpUtilsTest.upload方法
		//图片只有三天时间有效期
		if((System.currentTimeMillis()-imageLastTime)>259000){
			//演示项目资源放在了classpath，实际项目不能放在这里
			String path = msg.getRealPath()+"/image/e.png";
			try {
				imageId = WeixinUtils.upload(path, getToken(), "image");
				imageLastTime = System.currentTimeMillis();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		image.setMediaId(imageId);
		send.setImage(image);
		
		return MessageUtils.toXMLString(send, "xml");
	}
	
	/**
	 * 图片上传工具
	 * */
	public static String upload(String filePath, String accessToken,String type) throws Exception {
		File file = new File(filePath);
		if (!file.exists() || !file.isFile()) {
			throw new IOException("文件找不到！");
		}
		
		//临时素材时效为3天
		String url = Const.UPLOAD_URL1.replace("ACCESS_TOKEN", accessToken).replace("TYPE",type);
		
		URL urlObj = new URL(url);
		HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();

		con.setRequestMethod("POST"); 
		con.setDoInput(true);
		con.setDoOutput(true);
		con.setUseCaches(false); 

		//设置请求头
		con.setRequestProperty("Connection", "Keep-Alive");
		con.setRequestProperty("Charset", "UTF-8");

		//设置分段标识
		String BOUNDARY = "----------" + System.currentTimeMillis();
		con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

		StringBuilder sb = new StringBuilder();
		sb.append("--");
		sb.append(BOUNDARY);
		sb.append("\r\n");
		sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"\r\n");
		sb.append("Content-Type:application/octet-stream\r\n\r\n");

		byte[] head = sb.toString().getBytes("utf-8");

		//准备输出流
		OutputStream out = new DataOutputStream(con.getOutputStream());
		//写头信息
		out.write(head);

		//获取本地文件
		DataInputStream in = new DataInputStream(new FileInputStream(file));
		int bytes = 0;
		byte[] bufferOut = new byte[1024];
		while ((bytes = in.read(bufferOut)) != -1) {
			out.write(bufferOut, 0, bytes);
		}
		in.close();

		byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");

		out.write(foot);

		out.flush();
		out.close();

		StringBuffer buffer = new StringBuffer();
		BufferedReader reader = null;
		String result = null;
		try {
			//读取上传结果
			reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			if (result == null) {
				result = buffer.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				reader.close();
			}
		}
		
		//使用阿里的fastjson
		JSONObject jsonObj = JSONObject.parseObject(result);
		System.out.println(jsonObj);
		String typeName = "media_id";
		if(!"image".equals(type)){
			typeName = type + "_media_id";
		}
		String mediaId = jsonObj.getString(typeName);
		return mediaId;
	}
}
